﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Sockets;

using LumiSoft.Net.IMAP.Client;
using LumiSoft.Net.IMAP;
using LumiSoft.Net;
using Entity;
using Utility;

namespace IMAPService
{
    public class IMAPService
    {
        public static IMAP_Client Connection(UserAccount _ua)//建立IMAP连接
        {
            string[] _temp = _ua.MailAddress.Split('@');

            try
            {
                IMAP_Client _service = new IMAP_Client();
                _service.Connect(_ua.ReciveServer, _ua.ReciveServerPort);
                _service.Authenticate(_temp[0], _ua.MailPassword);
                return _service;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        public static List<MailFolder> GetFolderList(UserAccount _ua, MailFolderType _folderType, string _folderID)//获取文件夹列表，只支持根目录
        {
            IMAP_Client _service = ConnectionCache.Connections["IMAP_" + _ua.MailAddress] as IMAP_Client;

            List<MailFolder> _list = new List<MailFolder>();
            if (_folderType == MailFolderType.MsgRoot)
            {
                string[] _folders = _service.GetFolders();
                for (int i = 0; i < _folders.Length; i++)
                {
                    MailFolder _folder = new MailFolder();
                    _folder.FolderID = _folders[i];
                    _folder.DisplayName = IMAPDeconde(_folders[i]);
                    _list.Add(_folder);
                }
            }
            else
            {
                _list = null;
            }

            return _list;
        }

        public static void GetMailList(UserAccount _ua, string _folderID, bool _isInit)//获取邮件列表
        {
            MailList _list = new MailList();
            List<string> _mailInDB = new List<string>();//数据库里已有邮件列表，用来存现存邮件的UID
            IMAP_Client _service = ConnectionCache.Connections["IMAP_" + _ua.MailAddress] as IMAP_Client;
            _service.SelectFolder(_folderID);
            IMAP_FetchItem[] _fetchItem = _service.FetchMessages(0, -1, false, true, true);
            for (int i = 0; i < _fetchItem.Length; i++)
            {
                if (!_mailInDB.Contains(_fetchItem[i].UID.ToString()))
                {
                    IMAP_FetchItem[] _item = _service.FetchMessages(_fetchItem[i].UID, _fetchItem[i].UID, true, false, true);
                    //IMAP_FetchItem[] _item = _service.FetchMessages(1320822596, 1320822596, true, false, true);
                    Mail _mail = MailTools.MailParser(_item[0].UID.ToString(), _item[0].Data);

                    _list.MailItems.Add(_mail);
                }
            }
        }

        private static string IMAPDeconde(string folder)//IMAP文件夹名称解码
        {
            string rtn = "", base64;
            int index = 0;

            Regex regAsis = new Regex(@"\G([^&]+)");
            Regex reg26 = new Regex(@"\G\&-");
            Regex regDecode = new Regex(@"\G\&([A-Za-z0-9+,]+)-?");
            Regex regComma = new Regex(@",");

            while (index < folder.Length)
            {
                Match m;
                m = regAsis.Match(folder, index);
                if (m.Success)
                {
                    index = index + m.Length;
                    rtn = rtn + m.Value;
                    continue;
                }

                m = reg26.Match(folder, index);
                if (m.Success)
                {
                    index = index + m.Length;
                    rtn = rtn + "&";
                    continue;
                }

                m = regDecode.Match(folder, index);
                if (m.Success)
                {
                    index = index + m.Length;
                    base64 = m.Value.Substring(1, m.Value.Length - 2);
                    base64 = regComma.Replace(base64, "/");
                    int mod = base64.Length % 4;

                    if (mod > 0) base64 = base64.PadRight(base64.Length + (4 - mod), '=');
                    base64 = Encoding.GetEncoding("UTF-16BE").GetString(Convert.FromBase64String(base64));
                    rtn = rtn + base64;
                    continue;
                }
            }

            return rtn;
        }

        private static string IMAPEncode(string folder)//IMAP文件夹名称编码
        {
            string rtn = "", base64;
            int index = 0;

            Regex regAsis = new Regex(@"\G(?:[\x20-\x25\x27-\x7e])+");
            Regex reg26 = new Regex(@"\G&");
            Regex regEncode = new Regex(@"\G(?:[^\x20-\x7e])+");
            Regex regEq = new Regex(@"=+$");
            Regex regSlash = new Regex(@"\/");

            while (index < folder.Length)
            {
                Match m;
                m = regAsis.Match(folder, index);

                if (m.Success)
                {
                    index = index + m.Length;
                    rtn = rtn + m.Value;
                    continue;
                }

                m = reg26.Match(folder, index);

                if (m.Success)
                {
                    index = index + m.Length;
                    rtn = rtn + "&-";
                    continue;
                }

                m = regEncode.Match(folder, index);

                if (m.Success)
                {
                    index = index + m.Length;
                    base64 = Convert.ToBase64String(Encoding.GetEncoding("UTF-16BE").GetBytes(m.Value));
                    base64 = regEq.Replace(base64, "");
                    base64 = regSlash.Replace(base64, ",");

                    rtn = rtn + "&" + base64 + "-";
                    continue;
                }
            }
            return rtn;
        }

    }
}
